﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Co9320.NamaAlert.Engine.TagService
{
	internal enum ParseElementType
	{
		Irregular,
		Tag,
		Sentence,
		LineBreak,
		EOF
	}

	internal class ParseElement
	{
		public ParseElement(string Value, ParseElementType Type)
		{
			this.Value = Value;
			this.Type = Type;
		}

		public ParseElementType Type
		{
			get;
			private set;
		}

		public string Value
		{
			private set;
			get;
		}

	}


	internal class Parser
	{
		private Lexer lex;

		public Parser(Lexer lex)
		{
			if (lex == null)
			{
				this.lex = new Lexer(null);
			}
			else
			{
				this.lex = lex;
			}

			this.lex.Next();
		}

		public ParseElement GetElement()
		{
			string Value = null;

			switch (lex.Current.Type)
			{
				case TokenType.EOF:
					return new ParseElement(null, ParseElementType.EOF);

				case TokenType .LineBreak:
					Value=lex.Current.Value;
					lex.Next();
					return new ParseElement(Value, ParseElementType.LineBreak);
				
				case TokenType.LeftBracket:
					return GetTag();

				case TokenType.String:
					Value = lex.Current.Value;
					lex.Next();
					return new ParseElement(Value, ParseElementType.Sentence);

				default:
					return new ParseElement(GetAll(), ParseElementType.Irregular);
			}
		}

		private string GetAll()
		{
			StringBuilder bld = new StringBuilder();

			bld.Append(lex.Current.Value);

			while (lex.Next())
			{
				if (lex.Current.Type != TokenType.LineBreak)
				{
					bld.Append(lex.Current.Value);
				}
				else
				{
					break;
				}
			}
			return bld.ToString();
		}

		private ParseElement GetTag()
		{
			string inspect;

			if (lex.Current.Value == "[")
			{
				inspect = "]";
			}
			else
			{
				inspect = "】";
			}

			lex.Next();

			switch (lex.Current.Type)
			{
				case TokenType.String:
					if (lex.Peek.Type == TokenType.RightBracket && lex.Peek.Value==inspect)
					{
						string Value = lex.Current.Value;
						lex.Next();//Consume current string token.
						lex.Next();//Consume right bracket token.
						return new ParseElement(Value, ParseElementType.Tag);
					}
					else
					{
						return new ParseElement(GetAll(), ParseElementType.Irregular);
					}
				
				case TokenType.RightBracket:
					lex.Next();//Consume current right bracket token.
					return new ParseElement("", ParseElementType.Tag);

				default:
					return new ParseElement(GetAll(), ParseElementType.Irregular);
			}
		}

	}
}

